import csv
import logging

from datetime import datetime

import codecs
from django.contrib import admin, messages

# Register your models here.
from django.db.models import Q
from django.http import HttpResponse
from django.utils.safestring import mark_safe

from interview import dingtalk
from interview.models import Candidate
from interview.candidate_fieldset import default_fieldsets, default_fieldsets_first, default_fieldsets_second
from jobs.models import Resume

logger = logging.getLogger(__name__)

exportable_fields = ("username", "city", "phone", "bachelor_school", "degree", "first_result", "first_interviewer_user",
                     "second_result", "second_interviewer_user", "hr_result", "hr_score", "hr_remark",
                     "hr_interviewer_user")


def export_model_as_csv(model_admin, request, queryset):
    response = HttpResponse(content_type="text/csv")
    fields_list = exportable_fields
    response['Content-Disposition'] = 'attachment; filename=recruitment-candidates-list-%s.csv' % \
                                      datetime.now().strftime("%Y-%m_%d-%H-%M-%S")
    # 写入表头
    response.write(codecs.BOM_UTF8)  # 解决中文乱码
    writer = csv.writer(response)
    writer.writerow(
        [queryset.model._meta.get_field(f).verbose_name.title() for f in fields_list]
    )

    for obj in queryset:
        # 单行记录
        csv_line_values = list()
        for field in fields_list:
            field_object = queryset.model._meta.get_field(field)
            field_value = field_object.value_from_object(obj)
            csv_line_values.append(field_value)
        writer.writerow(csv_line_values)
    logger.info("%s export %s candidate records" % (request.user, len(queryset)))
    return response


export_model_as_csv.short_description = u'导出为CSV文件'
export_model_as_csv.allowed_permissions = ('export',)


# 消息通知一面面试官
def notify_interviewer(modeladmin, request, queryset):
    candidates = ''
    interviewers = ''
    for obj in queryset:
        candidates = obj.username + ';' + candidates
        interviewers = obj.first_interviewer_user.username + ';' + interviewers
    dingtalk.send('候选人 %s 进入面试环节，亲爱的面试官，请准备好面试：%s' % (candidates, interviewers))
    messages.add_message(request, messages.INFO, "已经成功发送面试通知")


notify_interviewer.short_description = u'通知一面面试官'


class CandidateAdmin(admin.ModelAdmin):
    exclude = ("creator", "created_at", "updated_at")

    actions = [export_model_as_csv, notify_interviewer]

    # 当前用户是否有导出权限
    def has_export_permission(self, request):
        opts = self.opts
        return request.user.has_perm("%s.%s" % (opts.app_label, 'export'))

    list_display = (
        "username", "city", "bachelor_school", "get_resume", "first_score", "first_result",
        "first_interviewer_user", "second_result", "second_interviewer_user", "hr_score",
        "hr_result", "last_editor"
    )

    # 筛选
    list_filter = ("city", "first_result", "second_result", "hr_result", "first_interviewer_user",
                   "second_interviewer_user", "hr_interviewer_user")

    # 搜索
    search_fields = ("username", "phone", "email", "bachelor_school")

    # 排序
    ordering = ("hr_result", "second_result", "first_result")

    # 生成一个连接，将该方法传递给list_display
    @staticmethod
    def get_resume(obj):
        if not obj.phone:
            return ""
        resumes = Resume.objects.filter(phone=obj.phone)
        if resumes and len(resumes) > 0:
            return mark_safe(u'<a href="/resume/%s" target="_blank">%s</a>' % (resumes[0].id, "查看简历"))
        return ""

    get_resume_short_description = u"查看简历"
    get_resume_allow_tags = True

    @staticmethod
    def get_group_name(user):
        group_name = []
        for g in user.groups.all():
            group_name.append(g.name)
        return group_name

    # 列表页展示数据
    def get_queryset(self, request):
        qs = super(CandidateAdmin, self).get_queryset(request)
        group_names = self.get_group_name(request.user)
        # 如果是管理员或者hr的话，返回所有候选人信息
        if request.user.is_superuser or 'hr' in group_names:
            return qs
        # 否则返回当前面试官可以面试的候选人
        return Candidate.objects.filter(Q(first_interviewer_user=request.user) |
                                        Q(second_interviewer_user=request.user))

    # 动态设置readonly字段, 不同于readonly_fields = ('first_interviewer_user', 'second_interviewer_user')
    def get_readonly_fields(self, request, obj=None):
        # 查询用户所属的群组
        group_name = self.get_group_name(request.user)
        # 如果当前管理员属于面试官组，则不允许修改用户对应的面试官（面试官没有权限修改用户由哪个面试官来面试）
        if 'interviewer' in group_name:
            logger.info('interviewer is in user′s group for %s' % (request.user.username))
            return ('first_interviewer_user', 'second_interviewer_user')
        return ()

    # 指定哪些字段可以在列表页进行修改, 不同于list_editable = ('first_interviewer_user', 'second_interviewer_user')
    # django CandidateAdmin默认未实现该方法，我们需要覆盖符类方法中的list_editable
    def get_list_editable(self, request):
        # 查询用户所属的群组
        group_name = self.get_group_name(request.user)
        # 仅允许hr和管理员编辑面试官
        if 'hr' in group_name or request.user.is_superuser:
            return ('first_interviewer_user', 'second_interviewer_user')
        return ()

    # 在该方法中对list_editable进行覆盖
    def get_changelist_instance(self, request):
        self.list_editable = self.get_list_editable(request)
        return super(CandidateAdmin, self).get_changelist_instance(request)

    # 一面面试官仅填写一面反馈，二面面试管可以填写二面反馈
    def get_fieldsets(self, request, obj=None):
        group_name = self.get_group_name(request.user)
        if "interviewer" not in group_name:
            return default_fieldsets
        elif obj.first_interviewer_user == request.user:
            return default_fieldsets_first
        elif obj.second_interviewer_user == request.user:
            return default_fieldsets_second


admin.site.register(Candidate, CandidateAdmin)
